iT邦幫忙

2022 iThome 鐵人賽

DAY 30
0
Modern Web

Angular牙起來系列 第 30

# Day30 【牙起來】 彈跳互動視窗2 - Modal

  • 分享至 

  • xImage
  •  

Day30 【牙起來】 彈跳互動視窗2 - Modal

NgbModal 搭配NgbActiveModal - Angular

使用Angular彈跳視窗的元件作法的話,需要用到Angular中Bootstrap模組的這兩個物件

  • NgbActiveModal 指的是被激活、正被使用的彈跳視窗本身,就是子元件身上的物件
  • NgbModal 是呼叫彈跳視窗的父元件

父元件呼叫子元件彈跳視窗,彈窗元件被使用者點擊後,子元件將點擊的資訊傳給父元件

子元件(彈跳視窗) 注入NgbActiveModal服務
修改modal01-component.ts

import { Component, OnInit } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-modal01',
  templateUrl: './modal01.component.html',
  styleUrls: ['./modal01.component.css']
})
export class Modal01Component implements OnInit {

  constructor(private activeModal: NgbActiveModal) { }

  ngOnInit(): void {
  }

  confirm() {
    alert('您點擊了"是"');
    this.activeModal.close(true);
  }

  deny() {
    alert('您點擊了"否"');
    this.activeModal.close(false);
  }
}

修改樣板modal01.component.html

<div class="p-3" style="border: solid 1px black">
  <div class="modal-header">
    <h5 class="modal-title flex-fill">彈跳視窗標題</h5>
  </div>
  <div class="modal-body">
    <div class="mb-5">
      <p>請確認是否繼續進行?</p>
    </div>
    <div class="d-flex flex-wrap justify-content-center">
      <div class="w-50 btn bg-info" (click)="confirm()">是</div>
      <div class="w-50 btn bg-light" (click)="deny()">否</div>
    </div>
  </div>
</div>

父元件(需要用到此元件的地方) 注入 NgbModal 服務
修改app.component.ts

import { Component } from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { Modal01Component } from './modal01/modal01.component';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(private ngbModal: NgbModal) {
  }

  public openModal() {
    this.ngbModal.open(Modal01Component);
  }
}

修改樣板app.component.html
留下一個按鈕,點擊此按鈕後開啟彈跳視窗

<div class="text-center">
  <button (click)="openModal()">點擊我開啟彈跳視窗</button>
</div>

同時要修改app.module.ts,引入NgbModule套件

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { Modal01Component } from './modal01/modal01.component';

@NgModule({
  declarations: [
    AppComponent,
    Modal01Component
  ],
  imports: [
    BrowserModule,
    NgbModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

完成畫面

彈跳視窗出現會讓背景有微微變暗效果

此時的彈跳視窗是可以透過點擊背景按下ESC鍵來關閉視窗的

可以透過參數來修改

  • backdrop:滑鼠點擊背景關閉彈跳視窗
  • keyboard:鍵盤按下ESC按鍵關閉彈跳視窗

修改app.component.ts 父元件中呼叫彈跳視窗的地方

...

export class AppComponent {
  constructor(private ngbModal: NgbModal) {
  }

  public openModal() {
    this.ngbModal.open(Modal01Component, {
      size: 'xl',
      // fullscreen: 'sm',
      backdrop: 'static',
      keyboard: false,
    })
  }
}

回傳資訊給父元件

修改app.component.ts 父元件中呼叫彈跳視窗的地方
分成成功回傳回傳失敗兩個方法

回傳失敗代表使用者提前關閉了彈跳視窗,導致沒有任何回傳值

...

export class AppComponent {
  constructor(private ngbModal: NgbModal) {
  }

  public openModal() {
    const modal = this.ngbModal.open(Modal01Component)
    modal.result.then(
      (result) => {
        alert('按下其中一個按鈕' + result)
      },
      () => {
        alert('關閉視窗')
      }
    )
  }
}

回傳值來源 是前面子元件 modal01-component.ts 帶入 this.activeModal.close(); 的值
可以帶入各種型別,對不同的回傳值做不同處理

...

export class AppComponent {
  constructor(private ngbModal: NgbModal) {
  }

  public openModal() {
    const modal = this.ngbModal.open(Modal01Component)
    modal.result.then(
      (result) => { // 按下按鈕 close
        if (result === true){
          alert('使用者按下了"是"')
        } else {
          alert('使用者按下了"否"')
        }
      },
      (reason) => { // 關閉視窗 dismiss
        console.log(reason)
      }
    )
  }
}


兩個 () => {} 函式,分別代表成功與失敗的處理

成功的處理 result 帶著使用者按下按鍵的回傳結果
失敗的處理 reason 返回失敗原因:透過滑鼠關閉0、透過鍵盤關閉1

也可以使用 .then().catch() 方式

...

export class AppComponent {
  constructor(private ngbModal: NgbModal) {
  }

  public openModal() {
    const modal = this.ngbModal.open(Modal01Component)
    modal.result.then(
      (result) => { // 按下按鈕 close
        if (result === true){
          alert('使用者按下了"是"')
        } else {
          alert('使用者按下了"否"')
        }
      }
    ).catch(reason => { // 關閉視窗 dismiss
      console.log(reason)
    })
  }
}

上一篇
# Day29 【牙起來】 彈跳互動視窗 - Modal
系列文
Angular牙起來30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言